//
//  SpeechSynthesizer.swift
//  officialDemoNavi
//
//  Created by liubo on 10/11/16.
//  Copyright © 2016 AutoNavi. All rights reserved.
//

import Foundation
import AVFoundation
import UIKit

class SpeechSynthesizer: NSObject {
    public static let Shared = SpeechSynthesizer()
    
    public var speechSynthesizer: AVSpeechSynthesizer!
    public var didFinishBlock:((String?)->Void)?
    var speekText: String?
    
    private override init(){
        super.init()
        
        buildSpeechSynthesizer()
    }
    
    public func speak(_ aString: String,language:String,speekFinsh:((String?)-> Void)? = nil) {
        DPrint("=======语音播报内容：\(aString)=======")
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print(error.localizedDescription)
        }
        self.speechSynthesizer.stopSpeaking(at: .word)
        self.speekText = aString
        let aUtterance = AVSpeechUtterance(string: aString)
        aUtterance.voice = AVSpeechSynthesisVoice(language: language)
        aUtterance.volume = 1
//        aUtterance.rate = 0.1
        aUtterance.pitchMultiplier = 1
        self.speechSynthesizer.speak(aUtterance)
        self.speechSynthesizer.delegate = self
        self.didFinishBlock = speekFinsh
    }
 
    public func isSpeaking() -> Bool {
        return self.speechSynthesizer.isSpeaking
    }
    
    public func stopSpeak() {
        self.speechSynthesizer.stopSpeaking(at: .word)
    }
    
    public func buildSpeechSynthesizer() {
        
        //简单配置一个AVAudioSession以便可以在后台播放声音，更多细节参考AVFoundation官方文档
        let session = AVAudioSession.sharedInstance()
        if #available(iOS 14.5, *) {
            if let error = try? session.setCategory(.playAndRecord, options:[.mixWithOthers, .duckOthers, .allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP, .allowAirPlay, .overrideMutedMicrophoneInterruption]) {
                NSLog("AudioSession Error:\(error)")
            }
        } else {
            if let error = try? session.setCategory(.playAndRecord, options:[.mixWithOthers, .duckOthers, .allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP, .allowAirPlay]) {
                NSLog("AudioSession Error:\(error)")
            }
        }
        try?session.setActive(true)
                
        self.speechSynthesizer = AVSpeechSynthesizer()
        if #available(iOS 13.0, *) {
            self.speechSynthesizer.usesApplicationAudioSession = false
        } else {
            // Fallback on earlier versions
        }
        self.speechSynthesizer.delegate = self
        
        kNOTIFY_ADD(observer: self, selector: #selector(audioRouteChange), name:AVAudioSession.routeChangeNotification.rawValue , object: session)
    }
       
    
    /// 继续播放后台背景音乐, 取消激活当前应用的AVAudioSession
    func resumebackgroundsoundwitherror()  {
        let session = AVAudioSession.sharedInstance()
        try?session.setActive(true, options: .notifyOthersOnDeactivation)
    }
    
    /// 暂停后台背景音乐的播放，激活当前应用的AVAudioSession
    func pausebackgroundsoundwitherror(){
        let session = AVAudioSession.sharedInstance()
        if #available(iOS 14.5, *) {
            if let error = try? session.setCategory(.playAndRecord, options:[.mixWithOthers, .duckOthers, .allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP, .allowAirPlay, .overrideMutedMicrophoneInterruption]) {
                NSLog("AudioSession Error:\(error)")
            }
        } else {
            if let error = try? session.setCategory(.playAndRecord, options:[.mixWithOthers, .duckOthers, .allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMixWithOthers, .allowBluetoothA2DP, .allowAirPlay]) {
                NSLog("AudioSession Error:\(error)")
            }
        }
        try?session.setActive(true)
    }
    
    @objc func audioRouteChange(notification:NSNotification){
        ///声道切换
        if let userInfo = notification.userInfo,
           let routeChangeReason = userInfo[AVAudioSessionRouteChangeReasonKey] as? AVAudioSession.RouteChangeReason ,
           let changeResonDescription = userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? [AVAudioSessionPortDescription] {
            print(routeChangeReason)
            switch routeChangeReason {
            case .oldDeviceUnavailable:
                if changeResonDescription[1].portType == AVAudioSession.Port.headphones {
                    //停止声音
                    DPrint("停止声音")
                } else {
                    //播放声音
                    DPrint("播放声音")
                }
                break
            default: break
                //停止声音
            }
        }
    }
}


extension SpeechSynthesizer:AVSpeechSynthesizerDelegate{
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance){
        self.didFinishBlock?(self.speekText)
    }
}
